/**************基于51单片机的数字音乐盒***********/

#include <REGX52.H>
#include "Tim.h"
#include "Delay.h"
#include "LCD1602.h"



/****定义按键引脚****/
sbit KEY1 = P1^0;
sbit KEY2 = P1^1;
sbit KEY3 = P1^2;
sbit KEY4 = P1^3;
sbit KEY5 = P1^4;

/****蜂鸣器****/
#define SPEED   500  //四分音符500ms
sbit Buzzer = P2^7;		//蜂鸣器引脚定义

//音符与索引对应表，P：休止符，L：低音，M：中音，H：高音，下划线：升半音符号#
#define P	0
#define L1	1
#define L1_	2	//Ctrl+shift+F可以替换变量字母
#define L2	3
#define L2_	4
#define L3	5
#define L4	6
#define L4_	7
#define L5	8
#define L5_	9
#define L6	10
#define L6_	11
#define L7	12
#define M1	13
#define M1_	14
#define M2	15
#define M2_	16
#define M3	17
#define M4	18
#define M4_	19
#define M5	20
#define M5_	21
#define M6	22
#define M6_	23
#define M7	24
#define H1	25
#define H1_	26
#define H2	27
#define H2_	28
#define H3	29
#define H4	30
#define H4_	31
#define H5	32
#define H5_	33
#define H6	34
#define H6_	35
#define H7	36

//索引与频率对照表
unsigned int FreqTable[]={
	0,
	63628,63731,63835,63928,64021,64103,64185,64260,64331,64400,64463,64528,
	64580,64633,64684,64732,64777,64820,64860,64898,64934,64968,65000,65030,
	65058,65085,65110,65134,65157,65178,65198,65217,65235,65252,65268,65283,
};


unsigned char FreqSelect,MusicSelect;


unsigned char code Music_HuaHai[]={
	//花海---周杰伦
	//音符,时值,	
	//1行号
	P,	4,	M1,	4,	M2,	4,	M3,	4,	M5,	4,	M5,	4+2,	M3,	4,	M2,	4,	M1,	4,	M2,	4,	M3,	4,	P,	4,	
	//2行号
	M1,	4,	M2,	4,	M3,	4,	M7,	4,	H1,	4,	H1,	4,	M7,	4,	M6,	4,	M5,	4,	M6,	4,	M5,	4,	P,	4,	
	//3行号
	M1,	4,	M2,	4,	M3,	4,	M5,	4,	M5,	4+2,	M3,	4,	M2,	4,	M1,	4,	M2,	4,	M1,	4,	P,	4,	
	//4行号
	M1,	4,	M2,	4,	M3,	4,	M5,	4,	M5,	4+2,	M4,	4,	M4,	4,	M3,	4,	H1,	4,	M3,	4,	M2,	4,	P,	4,

	//最后一行
	M1,	4,	M2,	4,	M3,	4,	M5,	4,	M1,	4,	M1,	4+2,	L7, 4,	L6, 4,	L7, 4,	M1,	4,
	
	0xFF

};


unsigned char code Music_Castle_in_the_Sky[]={
	//《天空之城》
	//音符,时值,	
	//1行号
	P,	4,	P,	4,	P,	4,	M6,	2,	M7,	2,	//每一小节 时值都是16	
	H1,	4+2,	M7,	2,	H1,	4,	H3,	4,	M7,	4+4+4,	M3,	2,	M3,	2,
	
	//2
	M6,	4+2,	M5,	2,	M6, 4,	H1,	4,	
	M5,	4+4+4,	M3,	4,	
	M4,	4+2,	M3,	2,	M4,	4,	H1,	4,	
	//3
	M3,	4+4,	P,	2,	H1,	2,	H1,	2,	H1,	2,	
	M7,	4+2,	M4_,2,	M4_,4,	M7,	4,	
	M7,	8,	P,	4,	M6,	2,	M7,	2,	
	//4
	H1,	4+2,	M7,	2,	H1,	4,	H3,	4,	
	M7,	4+4+4,	M3,	2,	M3,	2,	
	M6,	4+2,	M5,	2,	M6, 4,	H1,	4,	
	//5
	M5,	4+4+4,	M2,	2,	M3,	2,	
	M4,	4,	H1,	2,	M7,	2+2,	H1,	2+4,	
	H2,	2,	H2,	2,	H3,	2,	H1,	2+4+4,	
	//6
	H1,	2,	M7,	2,	M6,	2,	M6,	2,	M7,	4,	M5_,4,	
	M6,	4+4+4,	H1,	2,	H2,	2,	
	H3,	4+2,	H2,	2,	H3,	4,	H5,	4,	
	//7
	H2,	4+4+4,	M5,	2,	M5,	2,	
	H1,	4+2,	M7,	2,	H1,	4,	H3,	4,	
	H3,	4+4+4+4,
	
	//8
	M6,	2,	M7,	2,	H1,	4,	M7,	4,	H2,	2,	H2,	2,	
	H1,	4+2,	M5,	2+4+4,	
	H4,	4,	H3,	4,	H3,	4,	H1,	4,	
	//9
	H3,	4+4+4,	H3,	4,	
	H6,	4+4,	H5,	4,	H5,	4,	
	H3,	2,	H2,	2,	H1,	4+4,	P,	2,	H1,	2,
	
	//10
	H2,	4,	H1,	2,	H2,	2,	H2,	4,	H5,	4,	
	H3,	4+4+4,	H3,	4,	
	H6,	4+4,	H5,	4+4,
	
	//11
	H3,	2,	H2,	2,	H1,	4+4,	P,	2,	H1,	2,	
	H2,	4,	H1,	2,	H2,	2+4,	M7,	4,	
	M6,	4+4+4,	P,	4,
	
	0xFF
};


/*变量-标志位*/
unsigned char Music_Mode = 0;		//模式--- 0 暂停(停止)，123分别代表第123首歌曲
unsigned char Music_Mode_Select;	//模式选择按键
void main()
{
	Timer0_Init();	//初始化默认停止计时，TR0 = 0;
	LCD_Init();		
	//开机动画
	LCD_ShowString(1,1,"Welcome");	//第一行第一列显示ABC
	LCD_ShowString(2,1," ");		//
	while(1)
	{
		
		if (0 == KEY1) 	{Music_Mode_Select = 1;MusicSelect = 0;}
		if (0 == KEY2) 	{Music_Mode_Select = 2;MusicSelect = 0;}
		if (0 == KEY3) 	{Music_Mode_Select = 3;MusicSelect = 0;}
		if (0 == KEY4)
		{
			Music_Mode = Music_Mode_Select;	//将当前选择的模式赋值给Music_Mode变量
			TR0 = 1;	//音乐开启
		}
		if (0 == KEY5)	//如果按键5按下，暂停功能
		{	Music_Mode = 0;		}
		
		
		if (0 == Music_Mode)	TR0 = 0;	//暂停计时
		
		
		if (1 == Music_Mode)	//模式1 --- 歌曲1 --- 《花海》
		{
			if(Music_HuaHai[MusicSelect]!=0xFF)//如果不是停止标志位
			{
				FreqSelect = Music_HuaHai[MusicSelect];//选择音符对应的频率
				MusicSelect++;
				Delay((SPEED/4)*Music_HuaHai[MusicSelect]);//十六分音符是125ms，选择音符对应的时值
				MusicSelect++;
				TR0=0;
				Delay(5);	//音符间短暂停顿
				TR0=1;
			}
			else	//如果是停止标志位
			{
				TR0=0;
				while(1);//播放完死循环
			}
		}
		
		if (2 == Music_Mode)	//模式2 --- 歌曲2 --- 《天空之城》
		{
			if(Music_Castle_in_the_Sky[MusicSelect]!=0xFF)//如果不是停止标志位
			{
				FreqSelect = Music_Castle_in_the_Sky[MusicSelect];//选择音符对应的频率
				MusicSelect++;
				Delay((SPEED/4)*Music_Castle_in_the_Sky[MusicSelect]);//十六分音符是125ms，选择音符对应的时值
				MusicSelect++;
				TR0=0;
				Delay(5);	//音符间短暂停顿
				TR0=1;
			}
			else	//如果是停止标志位
			{
				TR0=0;
				while(1);//播放完死循环
			}
		}
		
		
	}
}



/****定时器0的中断服务子函数****/
void Timer0_Routine() interrupt 1  
{
	//1ms进一次，2ms一周期，频率f=500Hz
	if(FreqTable[FreqSelect])	//如果不是休止符
	{
		TL0 = FreqTable[FreqSelect]%256;		//设置定时初值
		TH0 = FreqTable[FreqSelect]/256;		//设置定时初值
		Buzzer=!Buzzer;//翻转蜂鸣器IO口
	}

}



//LCD1602显示示例代码
	/*LCD_ShowChar(1,1,'A');
	LCD_ShowString(1,3,"Hello");//第一行第三列显示ABC
	LCD_ShowNum(1,9,123,3);//第一行第九列显示123占三位
	LCD_ShowSignedNum(1,13,-66,2);//
	LCD_ShowHexNum(2,1,0xA8,2);//第二行第一列显示A8，占两位
	LCD_ShowBinNum(2,4,0xAA,8);*/

